<template>
    <el-form label-width="100px">
        <el-form-item label="SPU名称">
            <el-input placeholder="请你输入SPU名称" v-model="SpuParams.spuName"></el-input>
        </el-form-item>
        <el-form-item label="SPU品牌">
            <el-select v-model="SpuParams.tmId">
                <el-option v-for="(item, index) in AllTradeMark" :key="item.id" :label="item.tmName"
                    :value="item.id"></el-option>
            </el-select>
        </el-form-item>
        <el-form-item label="SPU描述">
            <el-input type="textarea" placeholder="请你输入SPU描述" v-model="SpuParams.description"></el-input>
        </el-form-item>
        <el-form-item label="SPU图片">
            <!-- v-model:fileList->展示默认图片
             action:上传图片的接口地址
             list-type:文件列表类型 -->
            <el-upload v-model:file-list="imgList" action="/api/admin/product/fileUpload" list-type="picture-card"
                :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :before-upload="handlerUpload"
                :headers="headers">
                <el-icon>
                    <Plus />
                </el-icon>
            </el-upload>

            <el-dialog v-model="dialogVisible">
                <img w-full :src="dialogImageUrl" alt="Preview Image" style="width:100%;height: 100%;" />
            </el-dialog>
        </el-form-item>
        <el-form-item label="SPU销售属性" style="margin: 10px 0px;">
            <!-- 展示销售下拉菜单 -->
            <el-select v-model="saleAttrIdAndValueName" style="width: 200px;"
                :placeholder="unSelectSaleAttr.length ? `还未选择${unSelectSaleAttr.length}个` : '无'">
                <el-option :value="`${item.id}:${item.name}`" v-for="(item, index) in unSelectSaleAttr" :key="item.id"
                    :label="item.name"></el-option>
            </el-select>
            <el-button :disabled="saleAttrIdAndValueName ? false : true" style="margin-left: 10px;" type="primary"
                size="default" icon="Plus" @click="addSaleAttr">添加属性</el-button>
            <!-- table展示销售属性与属性值的地方 -->
            <el-table border style="margin:10px 0px" :data="saleAttr">
                <el-table-column label="序号" type="index" align="center" width="80px"></el-table-column>
                <el-table-column label="销售属性名字" width="150px" prop="saleAttrName"></el-table-column>
                <el-table-column label="销售属性值">
                    <!-- row:即为当前SPU已有的销售属性对象 -->
                    <template #="{ row, $index }">
                        <el-tag v-for="(item, $index) in row.spuSaleAttrValueList" :key="item.id"
                            style="margin: 0px 5px" class="mx-1" closable
                            @close="row.spuSaleAttrValueList.splice($index, 1)">
                            {{ item.saleAttrValueName }}
                        </el-tag>
                        <el-input @blur="toLook(row)" v-model="row.saleAttrValue" v-if="row.flag == true"
                            placeholder="请你输入属性值" size="small" style="width: 100px;"></el-input>
                        <el-button @click="toEdit(row)" v-else type="primary" size="small" icon="Plus"></el-button>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="150px">
                    <template #="{ row, $index }">
                        <el-button type="primary" size="small" icon="Delete"
                            @click="saleAttr.splice($index, 1)"></el-button>
                    </template>
                </el-table-column>
            </el-table>
        </el-form-item>
        <el-form-item>
            <el-button :disabled="saleAttr.length > 0 ? false : true" type="primary" size="default"
                @click="save">保存</el-button>
            <el-button type="primary" size="default" @click="cancel">取消</el-button>
        </el-form-item>
    </el-form>
</template>

<script setup lang="ts">
import type { SpuData } from '@/api/product/spu/type';
import { ref, computed } from 'vue';
import { reqAllTradeMark, reqSpuImageList, reqSpuHasSaleAttr, reqAllSaleAttr, reqAddOrUpdateSpu } from '@/api/product/spu';
import type { SaleAttrValue, HasSaleAttr, SaleAttr, SpuImg, Trademark, AllTradeMark, SpuHasImg, SaleAttrResponseData, HasSaleAttrResponseData } from '@/api/product/spu/type';
import { ElMessage } from 'element-plus';

// el-upload 上传 http 请求头，携带 Token
// 引入用户相关的仓库
import useUserStore from '@/store/modules/user'
// 获取用户相关的小仓库：获取仓库内部token，登录成功以后携带给服务器
const userStore = useUserStore()
const headers = { Token: userStore.token }


let $emit = defineEmits(['changeScene'])
//点击取消按钮：通知父组件切换场景展示已有的spu数据
const cancel = () => {
    $emit('changeScene', { flag: 0, params: 'update' });
}
//子组件书写一个方法
const initHasSpuData = async (spu: SpuData) => {
    //存储已有的SPU对象，将来在模板中展示
    SpuParams.value = spu;
    //spu即为父组件传递过来的已有的SPU对象
    let result: AllTradeMark = await reqAllTradeMark();
    //获取某一个品牌旗下全部售卖商品的图片
    let result1: SpuHasImg = await reqSpuImageList((spu.id as number));
    //获取已有的SPU销售属性的数据
    let result2: SaleAttrResponseData = await reqSpuHasSaleAttr((spu.id as number))
    //获取整个项目全部SPU的销售属性
    let result3: HasSaleAttrResponseData = await reqAllSaleAttr();

    //存储全部品牌的数据
    AllTradeMark.value = result.data;
    //存储SPU对应商品图片
    imgList.value = result1.data.map(item => {
        return {
            name: item.imgName,
            url: item.imgUrl
        }
    })
    //存储已有的SPU的销售属性
    saleAttr.value = result2.data;
    //存储全部的销售属性
    allSaleAttr.value = result3.data;
}
let SpuParams = ref<SpuData>({
    category3Id: "",
    spuName: "",
    description: "",
    tmId: '',
    spuImageList: [],
    spuSaleAttrList: [],
});
//存储已有的SPU数据
let AllTradeMark = ref<Trademark[]>([])
//商品图片
let imgList = ref<SpuImg[]>([])
//已有的SPU销售值属性
let saleAttr = ref<SaleAttr[]>([])
//全部销售属性
let allSaleAttr = ref<HasSaleAttr[]>([])

//控制对话框的显示与隐藏效果
let dialogVisible = ref<boolean>(false)
//存储预览图片位置
let dialogImageUrl = ref<string>('')
//照片墙点击预览按钮的时候触发钩子
const handlePictureCardPreview = (file: any) => {
    dialogImageUrl.value = file.url;
    //弹出对话框
    dialogVisible.value = true;
}
//照片墙删除文件的钩子
const handleRemove = () => {

}
//照片墙上传成功之前的钩子：约束文件大小与类型
const handlerUpload = (file: any) => {
    if (file.type == 'image/png' || file.type == 'image/gif' || file.type == 'image/jpeg') {
        if (file.size / 1024 / 1024 < 3) {
            return true;
        } else {
            ElMessage({
                type: 'error',
                message: '上传的文件务3M以内'
            })
            return false;
        }
    } else {
        ElMessage({
            type: 'error',
            message: '上传的文件务必是PNG|JPG|GIF'
        })
        return false;
    }
}

//计算出当前SPU还未拥有的销售属性
let unSelectSaleAttr = computed(() => {
    //全部的销售属性：颜色、版本、是尺码
    //已有的销售属性：颜色、版本
    let unSelectAttr = allSaleAttr.value.filter(item => {
        return saleAttr.value.every(item1 => {
            return item.name != item1.saleAttrName;
        })
    })
    return unSelectAttr
})
//收集还未选择的销售属性的ID与属性值的名称
let saleAttrIdAndValueName = ref<string>('')
//添加销售属性的方法
const addSaleAttr = () => {
    const [baseSaleAttrId, saleAttrName] = saleAttrIdAndValueName.value.split(':');
    //准备一个新的销售属性对象，将来带给服务器即可
    let newSaleAtrr: SaleAttr = {
        baseSaleAttrId: Number(baseSaleAttrId), // 这里是使用 Number() 进行数据类型转换
        saleAttrName,
        spuSaleAttrValueList: [],
    }
    //追加到数组当中
    saleAttr.value.push(newSaleAtrr)
    //清空收集的数据
    saleAttrIdAndValueName.value = '';
}
//属性值按钮的点击事件
const toEdit = (row: SaleAttr) => {
    //点击按钮的时候，input组件显示->编辑模式
    row.flag = true;
    row.saleAttrValue = ''
}
//表单元素失去焦点的事件回调
const toLook = (row: SaleAttr) => {
    //整理收集的属性的ID与属性值的名字
    const { baseSaleAttrId, saleAttrValue } = row;
    //整理成服务器需要的属性形式
    let newSaleAtrrValue: SaleAttrValue = {
        baseSaleAttrId,
        saleAttrValueName: (saleAttrValue as string)
    }
    //非法情况判断
    if ((saleAttrValue as string).trim() == '') {
        ElMessage({
            type: 'error',
            message: '属性值不能为空'
        })
        return;
    }
    //重复值判断
    let repeat = row.spuSaleAttrValueList.find(item => {
        return item.saleAttrValueName == saleAttrValue;
    })
    if (repeat) {
        ElMessage({
            type: 'error',
            message: '属性值重复'
        })
        return;
    }

    //追加新的属性值对象
    row.spuSaleAttrValueList.push(newSaleAtrrValue);
    //切换为查看模式
    row.flag = false;
}
//保存按钮的回调
const save = async () => {
    //整理参数
    //1、照片墙
    SpuParams.value.spuImageList = imgList.value.map((item: any) => {
        return {
            imgName: item.name,
            imgUrl: (item.response && item.response.data) || item.url
        }
    })
    //整理销售属性的数据
    SpuParams.value.spuSaleAttrList = saleAttr.value;
    console.log(SpuParams.value.spuSaleAttrList)
    let result = await reqAddOrUpdateSpu(SpuParams.value);
    console.log(result)
    if (result.code == 200) {
        ElMessage({
            type: 'success',
            message: SpuParams.value.id ? '更新成功' : '添加成功'
        })
        // 通知父组件切换场景为0
        $emit('changeScene', { flag: 0, params: SpuParams.value.id ? 'update' : 'add' });
    } else {
        ElMessage({
            type: 'error',
            message: SpuParams.value.id ? '更新失败' : '添加失败'
        })
    }
    //发请求：添加SPU|更新已有SPU
}
//添加一个新的SPU初始化请求方法
const initAddSpu = async (c3Id: number | string) => {
    //清空数据
    Object.assign(SpuParams.value, {
        id: 0,
        category3Id: '',
        spuName: '',
        description: '',
        tmId: '',
        spuImageList: [],
        spuSaleAttrList: [],
    })
    //清空照片墙
    imgList.value = [];
    saleAttr.value = [];
    saleAttrIdAndValueName.value = '';
    //存储三级分类ID
    SpuParams.value.category3Id = c3Id;
    //获取全部数据
    let result: AllTradeMark = await reqAllTradeMark();
    //获取所有销售属性
    let result1: HasSaleAttrResponseData = await reqAllSaleAttr();
    //存储数据
    AllTradeMark.value = result.data;
    allSaleAttr.value = result1.data;
}

//对外暴露
defineExpose({ initHasSpuData, initAddSpu })















</script>
<style scoped></style>